package com.tool4j.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.InvalidClaimException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import java.util.Date;
import java.util.Map;

/**
 * @author Deng.Weiping
 * @since 2023/10/30 17:40
 */
@Slf4j
public class JwtUtil {
    private static final Algorithm key = Algorithm.HMAC256("gkyujhtsrgarehdgjheras");
    //签名使用的密钥
    private static final Algorithm CHATGLM_KEY = Algorithm.HMAC256("Dm8chPEHt3WHvoVA");

    private static final String CHATGLM_API_KEY = "a3eb3067baf1cb3c8b974bbab7c6fd85";

    /**
     * 生成Token
     *
     * @return
     */
    public static String createToken(Long userId) {
        return "Bearer " + JWT.create()
                .withClaim("userId", userId)
                .withExpiresAt(DateUtil.offsetDay(new Date(), 30))
                .sign(key);
    }

    /**
     * 验证Token
     *
     * @param jwtStr
     * @return
     */
    public static Long verify(String jwtStr) {
        JWTVerifier build = JWT.require(key).build();
        try {
            //验签
            DecodedJWT verify = build.verify(jwtStr);
            byte[] bytes = Base64.decodeBase64(verify.getPayload());
            String json = new String(bytes);
            return Long.parseLong(JSONUtil.toBean(json, Map.class).get("userId").toString());
        } catch (AlgorithmMismatchException e) {
            //算法错误
            log.error("加密算法和解密算法不一致");
        } catch (SignatureVerificationException e) {
            //验签失败，验签pwd密码错误
            log.error("解密密码错误");
        } catch (TokenExpiredException e) {
            //token过期
            log.error("Token过期");
        } catch (InvalidClaimException e) {
            //获取不到对应的负荷信息
            log.error("获取不到对应的负荷信息");
        } catch (Exception e) {
            log.error("未获取到正确的userId", e);
        }
        return null;
    }

    public static String refreshToken(String jwtStr, Long userId) {
        JWTVerifier build = JWT.require(key).build();
        try {
            // 验签
            DecodedJWT verify = build.verify(jwtStr);
            // 获取 Token 的过期时间
            Date expiresAt = verify.getExpiresAt();
            if (expiresAt != null) {
                // 计算剩余时间（毫秒）
                long remainingTime = expiresAt.getTime() - System.currentTimeMillis();
                // 如果剩余时间小于某个阈值（例如 5 分钟），则刷新 Token
                if (remainingTime < 5 * 60 * 1000) {
                    return createToken(userId); // 生成新的 Token
                }
            }
        } catch (AlgorithmMismatchException e) {
            //算法错误
            log.error("加密算法和解密算法不一致");
        } catch (SignatureVerificationException e) {
            //验签失败，验签pwd密码错误
            log.error("解密密码错误");
        } catch (TokenExpiredException e) {
            //token过期
            log.error("Token过期");
        } catch (InvalidClaimException e) {
            //获取不到对应的负荷信息
            log.error("获取不到对应的负荷信息");
        } catch (Exception e) {
            log.error("未获取到正确的userId", e);
        }
        return null;
    }
}